#include "Inf_SC12B.h"
#include "Com_Debug.h"

// 第几个I2C 这个芯片就一个
#define I2C_MASTER_NUM 0
// 设置I2C时钟线频率  400KB 高速模式
#define I2C_MASTER_FREQ_HZ 400000
// 设置I2C数据写缓冲区大小 主设备不需要缓冲区
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
// 设置I2C数据读取缓冲区大小 主设备不需要缓冲区
#define I2C_MASTER_RX_BUF_DISABLE 0


/**
 * @brief 初始化I2C主设备配置
 *
 * 该函数用于配置I2C主设备的基本参数:
 * - 设置为主设备模式
 * - 配置SCL时钟线引脚
 * - 配置SDA数据线引脚
 * - 启用SCL引脚上拉电阻
 *
 * @note 此函数为静态函数,仅在模块内部使用
 */
static void i2c_master_init(void)
{
    int i2c_master_port = I2C_MASTER_NUM;

    i2c_config_t conf = {};
    // 主设备模式
    conf.mode = I2C_MODE_MASTER;
    // 时钟线
    conf.scl_io_num = SC12B_SCL;
    // 数据线
    conf.sda_io_num = SC12B_SDA;
    // 使能上拉电阻 默认高电平
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    // 使能上拉电阻 默认高电平
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    // 设置时钟线频率
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
    // 配置I2C
    i2c_param_config(i2c_master_port, &conf);
    // I2C 使能 0 中断表示不需要开启中断
    i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

/**
 * @brief 写入数据
 *
 * @param addr 数据地址
 * @param reg 数据长度
 */
static uint8_t Inf_i2c_master_write(uint8_t addr, uint8_t reg)
{
    uint8_t data[2] = {addr, reg};

    // 写入状态
    int ret;
    // 写入数据 1000 = 写入时间
    ret = i2c_master_write_to_device(I2C_MASTER_NUM, SC12B_ADDR, data, 2, 1000);
    return ret;
}

/**
 * @brief 读取数据
 *
 * @param addr dizhi
 * @return uint8_t
 */
static uint8_t Inf_i2c_master_read(uint8_t addr)
{
    uint8_t res_data;
    // &addr, 1 写入数据,假写真读
    i2c_master_write_read_device(I2C_MASTER_NUM, SC12B_ADDR, &addr, 1, &res_data, 1, 1000);
    return res_data;
}

uint8_t is_touch = 0;

/**
 * @brief 外部中断触发
 * 
 * @param gpio_num 
 */
void Inf_SC12B_ISR_Handler (void *gpio_num){
    // 修改状态
    is_touch = 1;
}

/**
 * @brief 外部引脚中断配置
 *
 */
static void Inf_SC12B_GPIO_INT(void)
{
    gpio_config_t gpio = {};
    // 输入模式
    gpio.mode = GPIO_MODE_INPUT;
    // 引脚
    gpio.pin_bit_mask = (1 << SC12B_INT);
    // 默认下拉
    gpio.pull_down_en = GPIO_PULLDOWN_ENABLE;
    gpio.pull_up_en = GPIO_PULLUP_DISABLE;
    // 上升沿触发
    gpio.intr_type = GPIO_INTR_POSEDGE;
    gpio_config(&gpio);

    // 创建中断优先级
    gpio_install_isr_service(0);
    // 添加中断回调函数
    gpio_isr_handler_add(SC12B_INT, Inf_SC12B_ISR_Handler, (void*) SC12B_INT);
}

/**
 * @brief   初始化电容按键
 *
 */
void Inf_SC12B_Init(void)
{
    // 初始化I2C
    i2c_master_init();
    // 初始化外部中断
    Inf_SC12B_GPIO_INT();
    // 写入灵敏度
    Inf_i2c_master_write(0x00, 0x25);
    Inf_i2c_master_write(0x01, 0x25);
}

// 获取电容按键值
Touch_Key Inf_SC12B_GetValue(void)
{
    // 默认没有按键
    Touch_Key touck_key = KEY_NO;

    uint16_t data = ((Inf_i2c_master_read(0x08) << 8) | (Inf_i2c_master_read(0x09)));
    switch (data)
    {
    case 0x8000:
        touck_key = KEY_0;
        break;
    case 0x4000:
        touck_key = KEY_1;
        break;
    case 0x2000:
        touck_key = KEY_2;
        break;
    case 0x1000:
        touck_key = KEY_3;
        break;
    case 0x0800:
        touck_key = KEY_7;
        break;
    case 0x0400:
        touck_key = KEY_5;
        break;
    case 0x0200:
        touck_key = KEY_6;
        break;
    case 0x0100:
        touck_key = KEY_4;
        break;
    case 0x0080:
        touck_key = KEY_M;
        break;
    case 0x0040:
        touck_key = KEY_8;
        break;
    case 0x0020:
        touck_key = KEY_9;
        break;
    case 0x0010:
        touck_key = KEY_SHARP;
        break;
    default:
        break;
    }

    // 4.返回结果
    return touck_key;
}

/**
 * @brief  获取按键值
 * 
 * @return Touch_Key 
 */
Touch_Key Inf_SC12B_GetKey(void){
        // 默认没有按键
        Touch_Key touck_key = KEY_NO;
        if (is_touch == 1)
        {
            touck_key = Inf_SC12B_GetValue();
            is_touch = 0;
            return touck_key;
        }
        
        return touck_key;
}